package daily_task

import (
	"go_server/game_server/constants"
	"go_server/game_server/dao/daily_dao"
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/game_server/world_manager"
	"go_server/zinx/ziface"
	"go_server/zinx/zlog"
	"go_server/zinx/znet"
	"time"
)

type GetDailyTaskListApi struct {
	znet.BaseRouter
}

// 显示每日任务列表
func (*GetDailyTaskListApi) Handle(request ziface.IRequest) {
	// 解析请求消息
	msg := &pb.GetDailyTaskListC2S{}
	if !util.PBParseRet(request, msg) {
		return
	}

	// 获取连接对象和角色ID
	conn := request.GetConnection()
	roleId := ServiceObj.GetRoleId(request)

	// 获取主线任务 当前章节下的所有任务配置
	baseDailyTaskList := config_manager.GetStcTableTask_SheetTaskListByType(constants.DAILY_TASK)
	if len(baseDailyTaskList) == 0 {
		world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DAILY_TASK_UNFIND, nil)
		return
	}

	baseDailyChestList := config_manager.GetStcTableActivityConfig_SheetActivityConfigList()
	if len(baseDailyChestList) == 0 {
		world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DAILY_CHEST_UNFIND, nil)
		return
	}

	dateKey := time.Now().Format("20060102") // 格式化日期
	fields := []string{"daily_task", "active", "chest_info"}
	row := daily_dao.GetDailyByDateKey(dateKey, roleId, fields) // 获取当前用户主线任务进度

	var active int32                            // 当日活跃度
	var hadGotChestIds []int32                  // 当日已领取宝箱ID集合
	taskIdToProgress := make(map[int32][]int32) // 当日任务进度

	if row != nil {
		active = row.Active

		if row.ChestInfo != nil {
			hadGotChestIds = row.ChestInfo
		}

		if row.DailyTask.Data() != nil {
			taskIdToProgress = row.DailyTask.Data()
		}
	}

	eventSet := util.NewSet[int32]()
	if hadGotChestIds != nil {
		eventSet.AddValue(hadGotChestIds)
	}

	dailyTaskList := make(map[int32]*pb.DailyTaskInfo)   // 任务详情存储map
	dailyChestList := make(map[int32]*pb.DailyChestInfo) // 任务详情存储map

	// 遍历任务
	for key := range baseDailyTaskList {
		dailyTaskInfo := &pb.DailyTaskInfo{}

		// 根据任务ID从玩家任务进度中获取任务信息
		taskInfo, exist := taskIdToProgress[key]
		if exist {
			dailyTaskInfo.TaskId = taskInfo[0]
			dailyTaskInfo.Process = taskInfo[1]
			dailyTaskInfo.State = taskInfo[2]
		} else {
			dailyTaskInfo.TaskId = key
			dailyTaskInfo.Process = 0
			dailyTaskInfo.State = 0
		}

		dailyTaskList[key] = dailyTaskInfo
	}

	// 遍历宝箱
	for key, value := range baseDailyChestList {
		dailyChestInfo := &pb.DailyChestInfo{}
		var state int32 = 0 // 未达标,不可领取

		if hadGotChestIds != nil && eventSet.Contains(key) {
			state = 2 // 已领取
		} else {
			if active >= value.Value {
				state = 1 // 可领取
			}
		}

		dailyChestInfo.ChestId = key
		dailyChestInfo.State = state

		dailyChestList[key] = dailyChestInfo
	}

	// 组装返回数据结构
	res := &pb.GetDailyTaskListS2C{
		Active:         active,
		DailyTaskList:  dailyTaskList,
		DailyChestList: dailyChestList,
	}

	// 发送返回消息
	conn.SendBuffPBMsg(uint32(pb.ProtocolManager_GetDailyTaskList), res)
}

// 显示每日任务列表 下行推送
func (*GetDailyTaskListApi) GetDailyTaskListApiS2C(roleId int64) *pb.GetDailyTaskListS2C {
	// 获取主线任务 当前章节下的所有任务配置
	baseDailyTaskList := config_manager.GetStcTableTask_SheetTaskListByType(constants.DAILY_TASK)
	if len(baseDailyTaskList) == 0 {
		zlog.Errorf("baseDailyTaskList 每日任务配置不存在")
		return nil
	}

	baseDailyChestList := config_manager.GetStcTableActivityConfig_SheetActivityConfigList()
	if len(baseDailyChestList) == 0 {
		zlog.Errorf("baseDailyChestList 每日任务进度宝箱配置不存在")
		return nil
	}

	dateKey := time.Now().Format("20060102") // 格式化日期
	fields := []string{"daily_task", "active", "chest_info"}
	row := daily_dao.GetDailyByDateKey(dateKey, roleId, fields) // 获取当前用户主线任务进度

	var active int32                            // 当日活跃度
	var hadGotChestIds []int32                  // 当日已领取宝箱ID集合
	taskIdToProgress := make(map[int32][]int32) // 当日任务进度

	if row != nil {
		active = row.Active

		if row.ChestInfo != nil {
			hadGotChestIds = row.ChestInfo
		}

		if row.DailyTask.Data() != nil {
			taskIdToProgress = row.DailyTask.Data()
		}
	}

	eventSet := util.NewSet[int32]()
	if hadGotChestIds != nil {
		eventSet.AddValue(hadGotChestIds)
	}

	dailyTaskList := make(map[int32]*pb.DailyTaskInfo)   // 任务详情存储map
	dailyChestList := make(map[int32]*pb.DailyChestInfo) // 任务详情存储map

	// 遍历任务
	for key := range baseDailyTaskList {
		dailyTaskInfo := &pb.DailyTaskInfo{}

		// 根据任务ID从玩家任务进度中获取任务信息
		taskInfo, exist := taskIdToProgress[key]
		if exist {
			dailyTaskInfo.TaskId = taskInfo[0]
			dailyTaskInfo.Process = taskInfo[1]
			dailyTaskInfo.State = taskInfo[2]
		} else {
			dailyTaskInfo.TaskId = key
			dailyTaskInfo.Process = 0
			dailyTaskInfo.State = 0
		}

		dailyTaskList[key] = dailyTaskInfo
	}

	// 遍历宝箱
	for key, value := range baseDailyChestList {
		dailyChestInfo := &pb.DailyChestInfo{}
		var state int32 = 0 // 未达标,不可领取

		if hadGotChestIds != nil && eventSet.Contains(key) {
			state = 2 // 已领取
		} else {
			if active >= value.Value {
				state = 1 // 可领取
			}
		}

		dailyChestInfo.ChestId = key
		dailyChestInfo.State = state

		dailyChestList[key] = dailyChestInfo
	}

	// 组装返回数据结构
	res := &pb.GetDailyTaskListS2C{
		Active:         active,
		DailyTaskList:  dailyTaskList,
		DailyChestList: dailyChestList,
	}

	return res
}
